home *** CD-ROM | disk | FTP | other *** search
- Subject: v13i022: VN newsreader, 1/88 version, Part04/05
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Bob Mcqueer <amdahl!rtech!rtech!bobm@UUNET.UU.NET>
- Posting-number: Volume 13, Issue 22
- Archive-name: vn.jan.88/part04
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # vn.c
- # help.c
- # pagefile.c
- # digest.c
- # brk.h
- # head.h
- # node.h
- # page.h
- # reader.h
- # server.h
- # tty.h
- # tune.h
- # vn.h
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'vn.c'" '(8371 characters)'
- if test -f 'vn.c'
- then
- echo shar: will not over-write existing file "'vn.c'"
- else
- cat << \SHAR_EOF > 'vn.c'
- /*
- vn news reader for visual page oriented display of news
- aimed at scanning large numbers of articles.
-
- Original program by Bob McQueer in several versions 1983-1986. Released
- into the public domain in 1986. While no copyright notice appears, the
- original author asks that a history of changes crediting the proper people
- be maintained.
-
- Bob McQueer
- {amdahl, sun, mtxinu, hoptoad, cpsc6a}!rtech!bobm
-
- History:
-
- (bobm@rtech) 5/86 - first "public" version
-
- (bobm@rtech) 12/86 - version incorporates:
-
- bug fixes:
- str_store NULL string bug
- not picking up first article in newsgroup
- RESTART terminal reset for exit to editor.
- skip whitespace in "empty" digest lines while unpacking
- DISTRIBUTION line in followups.
- :100%: prompt on last line in reader.
- interpretation of multiple negations -w -t options.
-
- Many thanks to several people who noted the first
- two bugs as well as fixes.
-
- Thank you to Karl Williamson for helpful information
- tracking down the "concept terminal" bug (RESTART).
-
- SYSV ifdef's adapted from those done by Larry Tepper
- at ATT Denver - sent in by Karl Williamson, drutx!khw.
- Many people submitted SYSV ifdef's - thank you all.
-
- print capability from reader from Karl Williamson,
- drutx!khw
-
- Changes to use alternate header lines for mail, from changes
- by Andy Marrinson, andy@icom.UUCP (ihnp4!icom!andy). Ifdef'ed
- to allow local configuration (bobm@rtech).
-
- "author_copy" file for followups, prevention of multiple
- "re: "'s, insert blank line and original author line
- before excerpted text from Andy Marrinson, andy@icom.UUCP
-
- Search string capability in reader, from Lawrie Brown,
- seismo!munnari!cdsadfa.oz!lpb (Australia). Somewhat
- modified by interaction with the :100%: bug.
-
- Arrow key support, adapted from changes by Lawrie Brown.
- Modified to simply not allow control keys for arrows (allowing
- SOME controls is too prone to problems, esp. with .vnkey), and
- to allow the PAGEARROW ifdef (bobm@rtech)
-
- prevention of followups to "mod" and "announce", from
- Lawrie Brown.
-
- OLDRC ifdef adapted from changes by Lawrie Brown. ADDRMUNGE
- added to allow OZ domain addressing changes from Australia
- to be grafted back in, and provide a hook for anybody else
- wanting to do something similar.
-
- Bob McQueer, bobm@rtech:
-
- a menu selection from the % command to jump to
- a new newsgroup
-
- linked list on hash table - no longer a compiled
- in limit for number of newsgroups
-
- .vnkey keystroke mapping file.
-
- options to get the % command list on entry, and to
- change how unsubscribed groups are handled for updates.
-
- allow configurable use of vs / ve pair for terminal
- handling.
-
- 8/87 (bobm@rtech)
-
- Server interface changes. Creation of vns_xxx routines
- formally defining how to attach vn to an abstracted
- news server, rearranged existing code to use that
- abstraction. Sourcefile list altered a good bit by
- the rearrangement. Some of this was splitting some
- routines out from vn.c into smaller modules. Reader
- code was altered a good bit to work through the
- ARTHEADER abstraction, rather than searching for
- header lines. Temp file writing code was the other
- area heavily affected. The std.c server interface
- essentially incorporates the old newsrc.c code, plus
- the old outgroup() and gethead() routines.
-
- vns_changes also included:
-
- Modification of mailer interface for MAILCHOOSE,
- getting rid of ADDRMUNGE (superseded by vns
- interface definition)
-
- Moved readstr() into the session loop code,
- allowing a lot of static declarations to be
- placed therein. Also made it possible to
- use strtok() underneath readstr().
-
- Made "save" write directly into file, rather
- than forking a cat (gee, that sounds perverse).
-
- Also fixes it so that "|" save convention works
- from reader.
-
- Digest unpacking has to know about header lines,
- unfortunately, so it has local definitions for
- some header lines.
-
- Incorporates:
-
- The much-discussed "continued header line" bug
- fix, of course. Includes the multiple header
- line nfgets() by Andrew Worsley, andrew@munnari.oz,
- with a couple cosmetic changes.
-
- Top / Middle / Bottom keys from Karl Williamson
- print capability from reader from Karl Williamson,
- drutx!khw
-
- Edit old save file changes from George Pavel,
- gp@lll-lcc.arpa. Used it to allow edit of
- the some other old strings, too.
-
- Fix for the bad number input bug on the choose
- new group from list feature, as reported by
- Dave Tallman, tallman@hc.arpa. His fix with
- a few minor changes.
-
- A couple save file tweaks - allow a "%s" in VNSAVE
- to specify individual directories by newsgroup.
- Allow a "w:" prefix on filename to write instead
- of appending, allow %d for article number in name.
-
- The VNEDITOR variable.
-
- Statistics collection ability.
-
- Update of .newsrc "read" number to reflect removed
- articles, preventing rescanning of group on next
- session.
-
- take out SIGHUP catching to avoid problems with
- message being output.
-
- key to print version being used.
-
- Bug fixes following 12/87 posting. Made this version 1/88 / res1.1
- to distinguish.
-
- Digest extraction in reader.c, fix from steve@mahendo. Thanks
- to steve@mahendo & greg@mahendo for tracking down digest
- extraction bugs. I obviously didn't beat on the feature enough
- after rearranging things to abstract the server interface.
- The digest extraction display is a little less informative,
- the price paid to allow mail & followup.
-
- SYS V ifdefs - svart.c, independently arrived at by several
- people - thank you. At the behest of a couple people I made
- it spawn a "mkdir" instead of punting by calling mknod.
-
- Fix bug which would cause vn to crash if article has
- no "From" / "Reply-to" / "Path" line. - std.c
-
- Fix bug preventing assignment of .newsrc to filesystem other
- than that containing user's HOME.
-
- Fix excessive allocation in hash.c
-
- Handle duplicate active list records more gracefully.
-
- term_set(RESTART) call added to recovery from being
- backgrounded in sig_set.c, in case something you ran while
- backgrounded messed up your terminal state. I lost the name
- of the person reporting the problem & fix - my apologies.
-
- display optimization in reader.c which repaints instead of
- scrolling if indicated by user's MORE variable. This came
- from Greg Earle, earle@mahendo. Modified slightly for
- cosmetic reasons & to fix a small folded-line bug.
-
- Known bugs:
-
- If your terminal init string contains a newline, I suspect you will
- get an initial "stopped on tty output" if you fire up backgrounded.
- Cooked mode until session is started probably saves us in a lot of
- cases where the init string contains no newlines. Can be fixed, but
- it's esoteric enough that I don't want to add another file to the
- "patched" list.
-
- non-erasure of stuff on prompt line when the new
- string includes an escape sequence (like PS1 maybe)
- because it doesn't realize that the escape sequence
- won't overprint the existing stuff
-
- control-w and update on exit may not update pages which have been
- scanned in funny orders by jumping into the middle of groups
-
- inaccurate numbers on '%' command results - reflect ranges, not
- actual numbers of articles.
-
- no arrow keys recognized which don't begin with <escape>
-
- doesn't know about the version 2.11 'm' in active list, or
- use the 'y' / 'n' either.
-
- crash due to embedding $\(\) type substring specifiers in regular
- expressions. Obscure and hard to fix in a proper and portable way.
- */
- #include <stdio.h>
- #include "node.h"
- #include "tty.h"
- #include "brk.h"
-
- extern int Lrec;
-
- extern NODE **Newsorder;
- extern int Ncount;
-
- extern int Listfirst, Nounsub;
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- /*
- initialize environment variables,
- scan .newsrc file, using any command line options present.
- */
- term_set (START);
- envir_set ();
- sig_set (BRK_IN);
-
- stat_start();
-
- hashinit();
- temp_open();
-
- vns_news (argc,argv,&Listfirst,&Nounsub);
-
- fw_done ();
-
- make_newsorder();
-
- tty_set (BACKSTOP);
-
- if (Lrec >= 0)
- session ();
- else
- {
- new_groups ();
- fprintf (stderr,"\nNo News\n");
- }
-
- tty_set (COOKED);
-
- /* exiting, don't worry about FLG_ECHG resetting */
- vns_write(Newsorder,Ncount);
-
- term_set (STOP);
- vns_exit(0);
-
- stat_end( Lrec >= 0 ? 1 : 0 );
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'help.c'" '(5499 characters)'
- if test -f 'help.c'
- then
- echo shar: will not over-write existing file "'help.c'"
- else
- cat << \SHAR_EOF > 'help.c'
- /*
- ** vn news reader.
- **
- ** help.c - print help
- **
- ** see copyright disclaimer / history in vn.c source file
- */
- #include <stdio.h>
- #include <setjmp.h>
- #include "config.h"
- #include "tty.h"
- #include "tune.h"
- #include "node.h"
- #include "page.h"
- #include "reader.h"
- #include "vn.h"
-
- extern int L_allow;
- extern int C_allow;
- extern int Digest;
- extern char *Contstr;
- extern char Cxptoi[], Cxrtoi[];
-
- /*
- Help message table. Character for command, plus its help
- message. Table order is order of presentation to user.
- */
- static struct HELPTAB
- {
- char cmd, *msg;
- int dig;
- char *amsg;
- }
- Helptab [] =
- {
- { QUIT, "quit", 1, NULL},
- { UP, "(or up arrow) move up [number of lines]", 1, NULL},
- { DOWN, "(or down arrow) move down [number of lines]", 1, NULL},
- #ifdef PAGEARROW
- { BACK, "(or left arrow) previous page [number of pages]", 1, NULL},
- { FORWARD, "(or right arrow) next page [number of pages]", 1, NULL},
- #else
- { BACK, "previous page [number of pages]", 1, NULL},
- { FORWARD, "next page [number of pages]", 1, NULL},
- #endif
- { TOPMOVE, "move to top of page", 1, NULL},
- { BOTMOVE, "move to bottom of page", 1, NULL},
- { ALTBOTTOM, "move to bottom of page (alternate L)", 1, NULL},
- { MIDMOVE, "move to middle of page", 1, NULL},
- { DIGEST, "unpack digest", 1, "exit digest"},
- { READ, "read article [number of articles]", 1, NULL},
- { ALTREAD, "read article (alternate 'r')", 1, NULL},
- { READALL, "read all articles on page", 1, NULL},
- { READSTRING, "specify articles to read", 1, NULL},
- { SAVE, "save or pipe article [number of articles]", 1, NULL},
- { SAVEALL, "save or pipe all articles on page", 1, NULL},
- { SAVESTRING, "specify articles to save", 1, NULL},
- { ALTSAVE, "specify articles to save (alternate ctl-s)", 1, NULL},
- { PRINT, "print article [number of articles]", 1, NULL},
- { PRINTALL, "print all article on page", 1, NULL},
- { PRINTSTRING, "specify articles to print", 1, NULL},
- { UPDATE, "update .newsrc status to cursor", 0, NULL},
- { UPALL, "update .newsrc status for whole newsgroup", 0, NULL},
- { UPSEEN, "update .newsrc status for all pages displayed", 0, NULL},
- { ORGGRP, "recover original .newsrc status for newsgroup", 0, NULL},
- { ORGSTAT, "recover all original .newsrc status", 0, NULL},
- { SSTAT, "display count of groups and pages - shown and total", 0, NULL},
- { GRPLIST, "list newsgroups with new article, updated counts", 0, NULL},
- { NEWGROUP, "specify newsgroup to display and/or resubscribe to", 1, NULL},
- { UNSUBSCRIBE, "unsubscribe from group", 0, NULL},
- { MARK, "mark/unmark article [number of articles]", 1, NULL},
- { ART_MARK, "mark/unmark article [number of articles]", 1, NULL},
- { UNMARK, "erase marks on articles", 1, NULL},
- { HEADTOG, "toggle flag for display of headers when reading", 1, NULL},
- { SETROT, "toggle rotation for reading", 1, NULL},
- { REDRAW, "redraw screen", 1, NULL},
- { UNESC, "escape to UNIX to execute a command", 1, NULL},
- { PRTVERSION, "show vn version", 1, NULL},
- { HELP, "show this help menu", 1, NULL}
- };
-
- #define HTSIZE (sizeof(Helptab)/sizeof(struct HELPTAB))
-
- /*
- help from main screen
- */
- help ()
- {
- int i,lcount,lim;
- term_set (ERASE);
- lim = L_allow + RECBIAS - 2;
- printf("%s\n",HELP_HEAD);
- lcount = HHLINES;
- for (i=0; i < (sizeof(Helptab))/(sizeof(struct HELPTAB)); ++i)
- {
- if (Digest && !(Helptab[i].dig))
- continue;
- ++lcount;
- if (Digest && Helptab[i].amsg != NULL)
- h_print (Cxptoi[Helptab[i].cmd],Helptab[i].amsg);
- else
- h_print (Cxptoi[Helptab[i].cmd],Helptab[i].msg);
- if (lcount >= lim)
- {
- printf ("\n%s",Contstr);
- getnoctl ();
- term_set (MOVE,0,lim+1);
- term_set (ZAP,0,strlen(Contstr));
- term_set (MOVE,0,lim-1);
- putchar ('\n');
- lcount = 0;
- }
- }
- if (lcount > 0)
- {
- printf ("\n%s",Contstr);
- getnoctl ();
- }
- }
-
- /*
- help from reader
- */
- help_rd()
- {
- h_print (Cxrtoi[PG_NEXT],HPG_NEXT);
- h_print (Cxrtoi[PG_QUIT],HPG_QUIT);
- h_print (Cxrtoi[PG_FLIP],HPG_FLIP);
- h_print (Cxrtoi[PG_REWIND],HPG_REWIND);
- h_print (Cxrtoi[PG_WIND],HPG_WIND);
- h_print (Cxrtoi[PG_SEARCH],HPG_SEARCH);
- h_print (Cxrtoi[PG_STEP],HPG_STEP);
- h_print (Cxrtoi[PG_REPLY],HPG_REPLY);
- h_print (Cxrtoi[PG_FOLLOW],HPG_FOLLOW);
- h_print (Cxrtoi[SAVE],HPG_SAVE);
- h_print (Cxrtoi[PRINT],HPG_PRINT);
- h_print (Cxrtoi[SETROT],HPG_ROT);
- h_print (Cxrtoi[HEADTOG],HPG_HEAD);
- h_print (Cxrtoi[PG_HELP],HPG_HELP);
- printf ("%s\n",HPG_DEF);
- }
-
- srch_help(c,dig)
- char c;
- int *dig;
- {
- int i;
-
- for (i=0; i < HTSIZE; ++i)
- if (Helptab[i].cmd == c)
- break;
- if (i < HTSIZE)
- {
- *dig = Helptab[i].dig;
- return (0);
- }
- return(-1);
- }
-
- /*
- h_print prints a character and a legend for a help menu.
- */
- static
- h_print(c,s)
- char c,*s;
- {
- if (strlen(s) > (C_allow - 14))
- s [C_allow - 14] = '\0';
- if (c > ' ' && c != '\177')
- printf (" %c - %s\n",c,s);
- else
- {
- switch (c)
- {
- case '\177':
- printf (" <delete> - %s\n",s);
- break;
- case '\040':
- printf (" <space> - %s\n",s);
- break;
- case '\033':
- printf (" <escape> - %s\n",s);
- break;
- case '\n':
- printf (" <return> - %s\n",s);
- break;
- case '\t':
- printf (" <tab> - %s\n",s);
- break;
- case '\b':
- printf (" <back sp> - %s\n",s);
- break;
- case '\f':
- printf ("<formfeed> - %s\n",s);
- break;
- case '\07':
- printf (" <bell> - %s\n",s);
- break;
- case '\0':
- printf (" <null> - %s\n",s);
- break;
- default:
- if (c < '\033')
- {
- c += 'a' - 1;
- printf(" control-%c - %s\n",c,s);
- }
- else
- printf(" %c0%o - %s\n",'\\',(int) c,s);
- break;
- }
- }
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'pagefile.c'" '(4093 characters)'
- if test -f 'pagefile.c'
- then
- echo shar: will not over-write existing file "'pagefile.c'"
- else
- cat << \SHAR_EOF > 'pagefile.c'
- /*
- ** vn news reader.
- **
- ** pagefile.c - routines to deal with page display tempfile
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- #include <stdio.h>
-
- #ifdef SYSV
- #include <sys/types.h>
- #include <fcntl.h>
- #endif
-
- #include <sys/file.h>
-
- #include "tune.h"
- #include "node.h"
- #include "page.h"
-
- extern int Ncount,Lrec,L_allow,Cur_page,C_allow;
- extern NODE **Newsorder;
- extern PAGE Page;
- extern int Digest;
-
- extern char *Aformat;
-
- extern char *T_head, *F_head, *L_head;
-
- static int Tdes; /* temp file descriptor */
- static int Pgsize; /* block size for seeking file */
-
- static NODE *Curgp = NULL; /* current newsgroup being written */
- static int Order = 0; /* order counter */
-
- /*
- routines which deal with the temp file containing
- display pages. Note the "invisible" file feature -
- tempfile is unlinked from /usr/tmp immediately. when
- Tdes is closed by UNIX the disk space will be given back.
- */
-
- temp_open ()
- {
- char tmpart [L_tmpnam];
- Lrec = -1;
- tmpnam (tmpart);
- Pgsize = sizeof (HEAD) + L_allow * sizeof(BODY);
- if ((Tdes = open(tmpart,O_RDWR|O_CREAT)) < 0)
- printex ("can't open %s",tmpart);
- unlink (tmpart);
- }
-
- /*
- ** set newsgroup for tempfile write
- */
- fw_group(ng,new,sub,rd,look)
- char *ng;
- int new;
- int sub;
- int rd;
- int look;
- {
- NODE *hashfind();
-
- if (Curgp != NULL && Page.h.artnum > 0)
- fw_flush();
-
- if ((Curgp = hashfind(ng)) == NULL)
- printex("fw_group - non-existent newsgroup, \"%s\"",ng);
- if (Curgp->order >= 0)
- printex("fw_group - repeat call on newsgroup, \"%s\"",ng);
- Curgp->order = Order;
- ++Order;
- fw_chg(new,sub,rd,look);
- Curgp->pages = 0;
- Curgp->pnum = Lrec+1;
- Page.h.name = Curgp->nd_name;
- Page.h.group = Curgp;
- Page.h.artnum = 0;
- }
-
- fw_chg(new,sub,rd,look)
- int new;
- int sub;
- int rd;
- int look;
- {
- Curgp->flags &= ~(FLG_NEW|FLG_SUB|FLG_SEARCH);
- if (new)
- Curgp->flags |= FLG_NEW;
- if (sub)
- Curgp->flags |= FLG_SUB;
- if (look)
- Curgp->flags |= FLG_SEARCH;
- Curgp->rdnum = Curgp->orgrd = Curgp->pgrd = rd;
- }
-
- /*
- ** write article to temp file.
- */
- fw_art(anum,subj,lines,author)
- int anum;
- char *subj;
- char *lines;
- char *author;
- {
- char tbuf[RECLEN];
- int idx;
-
- form_title(tbuf,subj,lines,author,anum);
- idx = Page.h.artnum;
- strcpy((Page.b)[idx].art_t, tbuf);
- (Page.b)[idx].art_id = anum;
- (Page.b)[idx].art_mark = ' ';
-
- ++(Page.h.artnum);
- if (Page.h.artnum >= L_allow)
- fw_flush();
- }
-
- fw_done()
- {
- if (Curgp != NULL && Page.h.artnum > 0)
- {
- /* correct if server was lying at fw_group() */
- Curgp->flags |= FLG_SEARCH;
- fw_flush();
- }
- }
-
- static
- fw_flush()
- {
- ++(Curgp->pages);
- ++Lrec;
- Curgp->flags |= FLG_PAGE;
- do_write();
- Page.h.artnum = 0;
- }
-
- find_page (n)
- int n;
- {
- long off,lseek();
- int i,last;
- Cur_page = n;
- off = Pgsize;
- off *= (long) n;
- lseek (Tdes, off, 0);
- if (read(Tdes, (char *) &(Page.h), sizeof(HEAD)) < sizeof(HEAD))
- printex("bad temp file read");
- i = Pgsize - sizeof(HEAD);
- if (read(Tdes, (char *) Page.b, i) < i)
- printex("bad temp file read");
- last = -1;
- for (i=0; i < Ncount; ++i)
- {
- if ((Newsorder[i])->pages > 0)
- {
- if ((Newsorder[i])->pnum > n)
- break;
- last = i;
- }
- }
- if (last < 0)
- printex ("can't find page %d",n);
- Page.h.group = Newsorder[last];
- Page.h.name = (Page.h.group)->nd_name;
- vns_gset(Page.h.name);
- }
-
- write_page ()
- {
- long off,lseek();
- if (!Digest)
- {
- off = Pgsize;
- off *= (long) Cur_page;
- lseek (Tdes, off, 0);
- do_write();
- }
- }
-
- static do_write()
- {
- int num;
-
- if (write(Tdes, (char *) &(Page.h), sizeof(HEAD)) < sizeof(HEAD))
- printex ("Bad temp file write");
- num = L_allow * sizeof(BODY);
- if (write(Tdes, (char *) Page.b, num) < num)
- printex ("Bad temp file write");
- }
-
- form_title (t,fn,fl,ff,n)
- char *t,*fn,*fl,*ff;
- int n;
- {
- char *ptr,*index();
- int i;
-
- if ((ptr = index(ff,'(')) != NULL && strlen(ptr) > 3)
- ff = ptr;
- sprintf (t,TFORMAT,fn,fl,ff);
- sprintf(ff,Aformat,' ',' ',n);
- i = C_allow - strlen(ff) + 1; /* remember newline in Aformat */
- t[i] = '\0';
- ctl_xlt(t);
- return (0);
- }
-
- /* replace control characters in titles */
- static ctl_xlt(s)
- char *s;
- {
- while (*s != '\0')
- {
- if (*s < ' ')
- *s += 'A' - 1;
- ++s;
- }
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'digest.c'" '(5687 characters)'
- if test -f 'digest.c'
- then
- echo shar: will not over-write existing file "'digest.c'"
- else
- cat << \SHAR_EOF > 'digest.c'
- /*
- ** vn news reader.
- **
- ** digest.c - digest unpacking routines
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- #include <stdio.h>
- #include "config.h"
- #include "head.h"
- #include "tune.h"
- #include "node.h"
- #include "page.h"
-
- extern int Digest;
- extern int L_allow;
- extern int C_allow;
- extern PAGE Page;
-
- extern FILE *vns_aopen();
-
- static char *Ext_pool = NULL;
- static char *Show[3];
-
- static char *Dhead = "Date: ";
- static char *Fhead = "From: ";
- static char *Lhead = "Lines: ";
- static char *Thead = "Subject: ";
-
- #define THDLEN 9
- #define LHDLEN 7
- #define FHDLEN 6
- #define DHDLEN 6
-
- digest_page (idx,skip)
- int idx;
- {
- char name[24];
- FILE *fp;
- int i,len,hl;
- char subj[RECLEN],date[RECLEN],from[RECLEN],junk[RECLEN],*str_store();
- long pos;
- ARTHEADER hdr;
-
- Digest = Page.b[idx].art_id;
-
- if ((fp = vns_aopen(Digest,&hdr)) == NULL)
- return (-1);
-
- subj[0] = date[0] = from[0] = junk[0] = '\0';
-
- /* skip over some articles if requested to */
- for (i=skip; i > 0; --i)
- {
- if (dig_advance(fp,from,subj,date,junk,&pos,&hl) < 0)
- return (-1);
- }
-
- for (i=0; i < L_allow &&
- (len = dig_advance(fp,from,subj,date,junk,&pos,&hl)) >= 0; ++i)
- {
- Page.b[i].art_id = i+1+skip;
- Page.b[i].art_mark = ' ';
- subj [C_allow] = '\0';
- from [C_allow] = '\0';
- sprintf (name,"%d",len);
- form_title (date,subj,name,from,100);
- strcpy (Page.b[i].art_t,date);
- }
-
- vns_aclose (fp);
-
- if (i == 0)
- return (-1);
-
- Page.h.artnum = i;
- return (i);
- }
-
- /*
- returns name of file containing "article", NULL for failure
- */
- char * digest_extract (s,art,hdr,start)
- char *s;
- int art;
- ARTHEADER *hdr;
- long *start;
- {
- FILE *fout,*fin;
- long pos;
- int lines,hl;
- char subj[RECLEN],date[RECLEN],from[RECLEN],bufr[RECLEN];
- char extra[RECLEN];
- char *index();
- long ftell();
- char *str_tpool(), *str_tstore();
-
- if (Ext_pool != NULL)
- str_tfree(Ext_pool);
- Ext_pool = str_tpool(3);
-
- if ((fin = vns_aopen(Digest,hdr)) == NULL)
- return (NULL);
-
- for ( ; art > 0; --art)
- {
- from[0] = subj[0] = date[0] = '\0';
- if ((lines = dig_advance(fin,from,subj,date,extra,&pos,&hl)) < 0)
- {
- vns_aclose(fin);
- return (NULL);
- }
- }
-
- tmpnam(s);
-
- if ((fout = fopen(s,"w")) == NULL)
- {
- vns_aclose(fin);
- unlink (s);
- return (NULL);
- }
-
- fseek(fin,0L,0);
-
- hdr->show_num = 0;
- hdr->show = Show;
- hdr->lines = lines;
- hdr->hlines = hl;
- if (subj[0] != '\0')
- {
- sprintf (bufr,"%s%s",Thead,subj);
- Show[hdr->show_num] = str_tstore(Ext_pool,bufr);
- ++(hdr->show_num);
- }
- if (from[0] != '\0')
- {
- sprintf (bufr,"%s%s",Fhead,from);
- Show[hdr->show_num] = str_tstore(Ext_pool,bufr);
- ++(hdr->show_num);
- }
- if (date[0] != '\0')
- {
- sprintf (bufr,"%s%s",Dhead,date);
- Show[hdr->show_num] = str_tstore(Ext_pool,bufr);
- ++(hdr->show_num);
- }
-
- while (fgets(bufr,RECLEN-1,fin) != NULL && bufr[0] != '\n')
- {
- if (strncmp(bufr,Fhead,FHDLEN) == 0)
- {
- fprintf (fout,"%s%s\n",Fhead,from);
- continue;
- }
- if (strncmp(bufr,Thead,THDLEN) == 0)
- {
- fprintf (fout,"%s%s\n",Thead,subj);
- continue;
- }
- if (strncmp(bufr,Dhead,DHDLEN) == 0)
- {
- fprintf (fout,"%s%s\n",Dhead,date);
- continue;
- }
- /* defer line count header - it comes last */
- if (strncmp(bufr,Lhead,LHDLEN) == 0)
- continue;
- fprintf (fout,"%s",bufr);
- }
-
- /* toss in extra header lines, line count header, extra newline */
- fprintf (fout,"%s%s%d\n\n",extra,Lhead,lines);
- *start = ftell(fout);
-
- fseek (fin,pos,0);
-
- while (fgets(bufr,RECLEN-1,fin) != NULL && strncmp(bufr,"--------",8) != 0)
- fprintf(fout,"%s",bufr);
-
- vns_aclose (fin);
- fclose (fout);
- return (s);
- }
-
- dig_list (s)
- char *s;
- {
- char *ptr,*out,*new,ns[L_tmpnam],tmp[RECLEN],*strtok();
- ARTHEADER hdr;
- long pos;
- int i;
-
- prinfo ("Extracting articles .....");
- strcpy (tmp,s);
- out = s;
-
- for (ptr = strtok(tmp," "); ptr != NULL; ptr = strtok(NULL," "))
- {
- i = atoi(ptr);
- if ((new = digest_extract(ns,i,&hdr,&pos)) != NULL)
- {
- sprintf (out,"%s ",new);
- out += strlen(new) + 1;
- }
- }
-
- *out = '\0';
-
- if (*s == '\0')
- strcpy (s,"NULLDIGEST");
- }
-
- dig_ulist (s)
- char *s;
- {
- char *strtok();
- for (s = strtok(s," "); s != NULL; s = strtok(NULL," "))
- unlink (s);
- }
-
- /*
- returns # lines in article, -1 for failure
- scans past article, returns position of start.
- also returns "extra" header lines encountered, WITH newlines.
- and counts total header lines.
- */
- static dig_advance (fp,from,subj,date,extra,pos,hcount)
- FILE *fp;
- char *from,*subj,*date,*extra;
- long *pos;
- int *hcount;
- {
- char buf[RECLEN];
- char *ptr, *index();
- int len,state,lcount;
-
- *hcount = lcount = state = 0;
- *extra = '\0';
-
- while (fgets(buf,RECLEN-1,fp) != NULL)
- {
- buf[(len = strlen(buf) - 1)] = '\0';
- for (--len ; len >= 0 && buf[len] == ' ' || buf[len] == '\t'; --len)
- buf[len] = '\0';
- ++len;
-
- switch(state)
- {
- case 0:
- /* skip blank lines before header */
- if (len == 0)
- break;
- state = 1; /* fall through */
- case 1:
- ++(*hcount);
- if (strncmp(buf,Fhead,FHDLEN) == 0)
- {
- strcpy (from,buf+FHDLEN);
- break;
- }
- if (strncmp(buf,Thead,THDLEN) == 0)
- {
- strcpy (subj,buf+THDLEN);
- break;
- }
- if (strncmp(buf,Dhead,DHDLEN) == 0)
- {
- strcpy (date,buf+DHDLEN);
- break;
- }
- /* put wierd header lines in extra */
- if ((ptr = index(buf,':')) != NULL)
- {
- *ptr = '\0';
- if (index(buf, ' ') == NULL)
- {
- *ptr = ':';
- sprintf(extra,"%s\n",buf);
- extra += strlen(extra);
- break;
- }
- *ptr = ':';
- }
- state = 2;
- --(*hcount);
-
- /* remember the newline we lopped off */
- *pos = ftell(fp)-strlen(buf)-1; /* fall through */
- case 2:
- ++lcount;
- if (strncmp("--------",buf,8) == 0)
- {
- --lcount;
- return (lcount);
- }
- break;
- }
- }
-
- return (-1);
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'brk.h'" '(750 characters)'
- if test -f 'brk.h'
- then
- echo shar: will not over-write existing file "'brk.h'"
- else
- cat << \SHAR_EOF > 'brk.h'
- /*
- ** vn news reader.
- **
- ** brk.h - codes for sig_set routine
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- /*
- state flags for handling breaks / values for sig_set calls.
- BRK_IN, BRK_SESS, BRK_READ and BRK_OUT are the states. All
- but BRK_INIT are used as calls to sig_set. BRK_RFIN indicates
- a return from BRK_READ to BRK_SESS (no jump location passed),
- */
- #define BRK_INIT 0 /* initial value, indicating uncaught signals */
- #define BRK_IN 1 /* in NEWSRC / article scanning phase */
- #define BRK_SESS 2 /* in page interactive session */
- #define BRK_READ 3 /* reading articles */
- #define BRK_RFIN 4 /* finished reading, return to old mode */
- #define BRK_OUT 5 /* NEWSRC updating phase */
-
- #define BRK_PR "really quit ? "
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'head.h'" '(2530 characters)'
- if test -f 'head.h'
- then
- echo shar: will not over-write existing file "'head.h'"
- else
- cat << \SHAR_EOF > 'head.h'
- /*
- ** vn news reader.
- **
- ** head.h - header line structure
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- /*
- ** How this thing works:
- **
- ** this structure is filled in by vns_aopen when opening an article.
- ** lines & hlines items will be used in providing percentage read prompts
- **
- ** show_num & show are the article information lines presented for the user
- ** when the "show headers" flag is turned off.
- **
- ** from and artid are used for mail salutations, etc.
- **
- ** The items used for mail replies, FOLLOWING the call to the mail massager
- ** if there is one, are mailcmd, mail_num, and mail. These are the items
- ** the massager should fill in. If no massager exists, vns_aopen will
- ** fill these in directly. If mail_err is non-null, the user won't be
- ** able to mail a reply to the article, and the item should be an error
- ** message explaining why. If there is a mailer function, the mailcmd
- ** item is not used.
- **
- ** The priv and priv_num items are for sole use of the server layer in
- ** the mail massager, mailer and poster functions.
- **
- ** The postcmd, post_num, and post arguments are used in treatment of
- ** followups. If post_err is non-null, followup won't be allowed, for
- ** the reason described therein. If there is a poster function, the
- ** postcmd item isn't used.
- **
- ** The header lines for inclusion in mail / followup files will open
- ** the file, and will be followed by one blank line. The lines are literal -
- ** all appropriate headers should be prepended, etc.
- **
- ** postcmd / mailcmd are used as format strings which are assumed to have a
- ** single %s in them some place for the placement of the users editted file.
- ** The result will be spawned as a command.
- */
-
- typedef struct
- {
- int lines; /* number of lines in article */
- int hlines; /* number of header lines in article */
- char *from; /* authors name */
- char *artid; /* article id */
- int show_num; /* number of extra lines for reader display */
- char **show; /* extra header lines */
- int priv_num; /* number of private arguments */
- char **priv; /* private server arguments */
- char *mail_err; /* mail reply error message */
- char *mailcmd; /* command line for mailer */
- int mail_num; /* number of header lines in mail reply file */
- char **mail; /* mail reply header lines */
- char *post_err; /* follow-up posting error message */
- char *postcmd; /* command line for followup poster */
- int post_num; /* number of header lines for followup file */
- char **post; /* followup header lines */
- } ARTHEADER;
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'node.h'" '(1580 characters)'
- if test -f 'node.h'
- then
- echo shar: will not over-write existing file "'node.h'"
- else
- cat << \SHAR_EOF > 'node.h'
- /*
- ** vn news reader.
- **
- ** node.h - NODE structure
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- /* newsgroup status flags */
- #define FLG_SUB 1 /* user subscribed to newsgroup */
- #define FLG_PAGE 2 /* a page exists to display */
- #define FLG_NEW 4 /* new newsgroup */
- #define FLG_ECHG 8 /* edit change by user */
- #define FLG_SEARCH 16 /* newsgroup was searched */
- #define FLG_ACC 32 /* newsgroup had articles accessed */
- #define FLG_STAT 64 /* stat's written */
-
- /*
- newsgroup information (hash table node)
-
- items unaccessed by server interface:
- next - hashtable link
- pnum - page number
- pages - number of pages for news display
- pgshwn - pages shown mask
- pgrd - article number on highest conecutively shown page
- order - order of appearance in Newsorder array.
- orgrd - original articles read number
-
- may be read following hashfind by server interface, but not written:
- nd_name - name of newsgroup (key to reach node by)
- this will be a permanent copy of the name.
- highnum - high article number in group
- lownum - low article number in group
-
- legal for vns_write to read, but not written by server interface:
- flags - bit mask of FLG_xxxx flags.
- rdnum - articles read.
-
- unused by vn user interface, intended for use by server interface:
- state - state variable. initted 0.
- data - arbitrary data pointer. initted NULL.
- */
- typedef struct _node
- {
- struct _node *next;
- char *nd_name;
- int highnum, lownum;
- int pnum, pages, rdnum, orgrd, pgrd;
- unsigned long pgshwn;
- unsigned flags;
- int order;
- unsigned state;
- char *data;
- } NODE;
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'page.h'" '(1152 characters)'
- if test -f 'page.h'
- then
- echo shar: will not over-write existing file "'page.h'"
- else
- cat << \SHAR_EOF > 'page.h'
- /*
- ** vn news reader.
- **
- ** page.h - display page structure
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- /*
- page display format and dependent parameters
- */
- #define HFORMAT "\n%s (page %d of %d):"
- #define DHFORMAT "\n%s (DIGEST EXTRACTION):"
- #define TFORMAT "%s ~ %s %s"
- #define AFORMAT "\n%c%c%d) " /* begin with newline - see show routine */
- #define AFLEN 5 /* min. char. in article id - depends on AFORMAT */
- #define CFORMAT "page %d of %d (%d shown), newsgroup %d of %d"
- #define RECBIAS 2 /* lines before articles - depends on HFORMAT */
- #define WRCOL 1 /* column of written mark. depends on AFORMAT */
- #define INFOLINE 0 /* HFORMAT TFORMAT leaves for use */
- #define REQLINES 7 /* required terminal lines for display, incl. help */
-
- /*
- newsgroup information for page display
- name - of group
- group - pointer to table entry
- artnum - number of articles
- */
- typedef struct
- {
- char *name;
- NODE *group;
- int artnum;
- } HEAD;
-
- /*
- article information - id (spool) number, title string, mark, written.
- */
- typedef struct
- {
- int art_id;
- char art_mark;
- char art_t[MAX_C-AFLEN];
- } BODY;
-
- typedef struct
- {
- HEAD h;
- BODY *b;
- } PAGE;
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'reader.h'" '(1537 characters)'
- if test -f 'reader.h'
- then
- echo shar: will not over-write existing file "'reader.h'"
- else
- cat << \SHAR_EOF > 'reader.h'
- /*
- ** vn news reader.
- **
- ** reader.h - article reading interface definitions
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- #define PAGE_MID ":more (%2d%%):"
- #define PAGE_NEXT ":next article:"
- #define PAGE_END ":end:"
- #define PAGE_NO ":?:"
- #define PPR_MAX 18 /* maximum length of PAGE prompts */
-
- /*
- reading commands: no control chars, add help message to helppg
- SAVE, PRINT, HEADTOG and SETROT are also recognized
- */
- #define HPG_HEAD "toggle header print flag"
- #define HPG_ROT "toggle rotation"
- #define HPG_SAVE "save article in a file"
- #define HPG_PRINT "print article"
- #define PG_NEXT 'n'
- #define HPG_NEXT "next article, if any"
- #define PG_QUIT 'q'
- #define HPG_QUIT "quit reading articles, if any more to read"
- #define PG_FLIP 'Q'
- #define HPG_FLIP "quit reading, and turn to next page of articles"
- #define PG_FOLLOW 'f'
- #define HPG_FOLLOW "post followup to article"
- #define PG_REPLY 'm'
- #define HPG_REPLY "send mail to author of article"
- #define PG_HELP '?'
- #define HPG_HELP "see this help menu"
- #define PG_REWIND 'r'
- #define HPG_REWIND "rewind article to beginning"
- #define PG_WIND 'e'
- #define HPG_WIND "seek to end of article (to next/end prompt)"
- #define PG_STEP '\n'
- #define HPG_STEP "next line"
- #define PG_SEARCH '/'
- #define HPG_SEARCH "search for regular expression in remainder of article"
- #define SEARCHFORM "search pattern (%s) ? "
- #define HPG_DEF "\n anything else to continue normal reading"
- #define HPG_EDEF "\n anything else to try reading next article, if any"
-
- #define ANFORM ":%s - %c for help:\n"
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'server.h'" '(151 characters)'
- if test -f 'server.h'
- then
- echo shar: will not over-write existing file "'server.h'"
- else
- cat << \SHAR_EOF > 'server.h'
-
- /*
- ** header files shared between vn and vns_xxxx server interface routines
- */
- #include "tune.h"
- #include "tty.h"
- #include "node.h"
- #include "head.h"
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'tty.h'" '(404 characters)'
- if test -f 'tty.h'
- then
- echo shar: will not over-write existing file "'tty.h'"
- else
- cat << \SHAR_EOF > 'tty.h'
- /*
- ** vn news reader.
- **
- ** tty.h - codes for tty_set and term_set
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- #define MOVE 100
- #define ERASE 101
- #define START 102
- #define STOP 103
- #define RUBSEQ 104
- #define ZAP 105
- #define ONREVERSE 106
- #define OFFREVERSE 107
- #define RESTART 108
-
- #define RAWMODE 200
- #define COOKED 201
- #define SAVEMODE 202
- #define RESTORE 203
- #define BACKSTOP 204
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'tune.h'" '(2198 characters)'
- if test -f 'tune.h'
- then
- echo shar: will not over-write existing file "'tune.h'"
- else
- cat << \SHAR_EOF > 'tune.h'
- /*
- ** vn news reader.
- **
- ** tune.h - system tuning parameters
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- /*
- ** buffer size needed for tmpnam()
- */
- #ifndef L_tmpnam
- #define L_tmpnam 48
- #endif
-
- /*
- ** hash table size. linked list type of table which can expand to
- ** arbitrary density, including densities > 100%. Number of entries
- ** will be number of newsgroups in active list. This should be a prime
- ** number ("long division" of string modulo table size hash function).
- */
- #define HASHSIZE 809
-
- /*
- ** maximum number of columns on terminal. If made smaller, there
- ** will be a savings in the size of the temporary file used
- ** for holding displays, at the penalty of not being able to use
- ** the entire screen width on terminals actually possessing more
- ** columns than this. A block roughly on the order of this value
- ** times the number of lines the terminal has is maintained per page in
- ** the temp file, and read / written as displays are interacted
- ** with. MIN_C put here because MAX_C > MIN_C. MIN_C is the minumum
- ** number of columns for which a "reasonable" display can be produced.
- ** before making it smaller, look at all uses of C_allow and variable
- ** to see that a setting that small won't screw up array bounds.
- */
- #define MAX_C 132
- #define MIN_C 36
-
- /*
- ** large size for general purpose local buffers. only used in automatic
- ** variable declarations. Used with fgets for buffer size when reading
- ** file records, to hold pathnames, commands, etc. Reduce if you blow
- ** out stack storage. If reduced too far, may eventually show up
- ** as syntax errors on interacting with vns_ routines, or command line
- ** botches.
- */
- #define RECLEN 1200
-
- /* block sizes for allocation routines */
- #define STRBLKSIZE 1800 /* string storage allocation block */
- #define NDBLKSIZE 50 /* NODE structures to allocate at a time */
-
- /*
- ** maximum number of articles to allow for processing in a single user
- ** list. Used only to declare an array of pointers on the stack, so it
- ** can be fair sized without much problem. In practicality, there is
- ** no use for it being larger than the greatest line length available
- ** on the CRT's being used.
- */
- #define MAXARTLIST 200
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'vn.h'" '(1654 characters)'
- if test -f 'vn.h'
- then
- echo shar: will not over-write existing file "'vn.h'"
- else
- cat << \SHAR_EOF > 'vn.h'
- /*
- ** vn news reader.
- **
- ** vn.h - general parameters
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- #define TRUE 1
- #define FALSE 0
-
- #define ED_MARK '>'
- #define ART_MARK '*'
- #define ART_WRITTEN '_'
- #define ART_UNWRITTEN ' '
-
-
- #define ANFORM ":%s - %c for help:\n"
- #define ANFLINES 1
- #define UDKFORM "undefined key - %c for help"
- #define HELPFORM "%c for help"
-
- /*
- command characters - don't use numerics or <ESC>
- ALTSAVE is a hack to avoid having to use ctl-s - XON/XOFF.
- Wanted to preserve "s" pneumonic and lower / control /cap
- convention.
- */
- #define DIGEST 'd'
- #define UP 'k'
- #define DOWN 'j'
- #define FORWARD '\012'
- #define BACK '\010'
- #define READ 'r'
- #define ALTREAD ' '
- #define READALL 'R'
- #define READSTRING '\022'
- #define SAVE 's'
- #define SAVEALL 'S'
- #define SAVESTRING '\023'
- #define ALTSAVE '\024'
- #define PRINT 'p'
- #define PRINTALL 'P'
- #define PRINTSTRING '\020'
- #define MARK 'x'
- #define UNMARK 'X'
- #define REDRAW '\014'
- #define QUIT 'q'
- #define SSTAT '#'
- #define GRPLIST '%'
- #define ORGGRP 'o'
- #define ORGSTAT 'O'
- #define UPDATE 'w'
- #define UNSUBSCRIBE 'u'
- #define UPALL 'W'
- #define UPSEEN '\027'
- #define UNESC '!'
- #define NEWGROUP 'n'
- #define HEADTOG 'h'
- #define SETROT 'z'
- #define HELP '?'
- #define TOPMOVE 'H'
- #define BOTMOVE 'L'
- #define ALTBOTTOM 'G'
- #define MIDMOVE 'M'
- #define PRTVERSION '"'
- #define HELP_HEAD "[...] = effect of optional number preceding command\n\
- pipes are specified by filenames beginning with |\n\
- articles specified as a list of numbers, title search string, or\n\
- * to specify marked articles. ! may be used to negate any\n"
-
- #define HHLINES 5 /* lines (CRs + 1) contained in HELP_HEAD */
- SHAR_EOF
- fi # end of overwriting check
- # End of shell archive
- exit 0
-